home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / ulib / rect.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  270 lines

  1. /***********************************************************************
  2.  * $Id: rect.c,v 0.80 1994/02/24 09:48:11 zhao Exp $
  3.  *
  4.  *.  Copyright(c) 1993,1994 by T.C. Zhao
  5.  *   All rights reserved.
  6.  *.
  7.  *
  8.  *   Relationships between rectangles. Any rectangle returned
  9.  *   must be used right away as the returned stuff is in
  10.  *   a static buffer (a rotating buffer is actually used).
  11.  ***********************************************************************/
  12.  
  13. #if !defined(lint) && defined(F_ID)
  14. char *id_rect = "$Id: rect.c,v 0.80 1994/02/24 09:48:11 zhao Exp $";
  15. #endif
  16.  
  17. #include "ulib.h"
  18.  
  19. #define MAX_RECT_BUF 15        /* max. rect buffer. */
  20.  
  21. /**************************************************************
  22.  *  Make a rectangle
  23.  **************************************************************/
  24.  
  25. const Rect_t *
  26. make_rect(int x, int y, int w, int h)
  27. {
  28.     static Rect_t dummy[MAX_RECT_BUF];
  29.     static int nb;
  30.     Rect_t *r = dummy + (nb++ % MAX_RECT_BUF);
  31.  
  32.     r->x = x;
  33.     r->y = y;
  34.     r->w = w;
  35.     r->h = h;
  36.  
  37.     return r;
  38. }
  39.  
  40. /***************************************************************
  41.  * rectangle might have a negative width or/and height, canonicalize
  42.  * so that width & height are positive
  43.  ***************************************************************/
  44. Rect_t *
  45. canonicalize_rect(Rect_t *r)
  46. {
  47.  
  48.     if (r->w < 0)
  49.       {
  50.       r->w = -r->w;
  51.       r->x -= r->w;
  52.       }
  53.  
  54.     if (r->h < 0)
  55.       {
  56.       r->h = -r->h;
  57.       r->y -= r->h;
  58.       }
  59.  
  60.     return r;
  61. }
  62.  
  63. /***************************************************************
  64.  * Test to see if point (x,y) is within rectangle *r
  65.  ***************************************************************/
  66. int
  67. inside_rect(int x, int y, const Rect_t *rin)
  68. {
  69.     Rect_t dummy;
  70.     Rect_t *r = &dummy;
  71.  
  72.     canonicalize_rect(copy_rect(r, rin));
  73.  
  74.     return (x >= r->x && x <= r->x + r->w - 1) &&
  75.     (y >= r->y && y <= r->y + r->h - 1);
  76. }
  77.  
  78. int
  79. equal_rect(const Rect_t *r1, const Rect_t *r2)
  80. {
  81.     return (r1->x == r2->x && r1->y == r2->y &&
  82.         r1->w == r2->w && r1->h == r2->h);
  83. }
  84.  
  85.  
  86. void
  87. shift_rect(Rect_t *r, int dx, int dy)
  88. {
  89.     r->x += dx;
  90.     r->y += dy;
  91. }
  92.  
  93. void
  94. inc_rect(Rect_t *r, int dx, int dy)
  95. {
  96.     r->w += dx;
  97.     r->h += dy;
  98. }
  99.  
  100. void
  101. set_rect(Rect_t *r, int x, int y, int w, int h)
  102. {
  103.     r->x = x;
  104.     r->y = y;
  105.     r->w = w;
  106.     r->h = h;
  107. }
  108.  
  109. Rect_t *
  110. copy_rect(Rect_t *des, const Rect_t *src)
  111. {
  112.     des->x = src->x;
  113.     des->y = src->y;
  114.     des->w = src->w;
  115.     des->h = src->h;
  116.  
  117.     return des;
  118. }
  119.  
  120. /***************************************************************
  121.  * Check if two rectangles overlap. If yes, return the union
  122.  * else return 0
  123.  ***************************************************************/
  124.  
  125. const Rect_t *
  126. union_rect(const Rect_t *r1, const Rect_t *r2)
  127. {
  128.     static Rect_t over[MAX_RECT_BUF];
  129.     static int nb;
  130.     register Rect_t *p = over + (nb++ % MAX_RECT_BUF);
  131.     register int xi, yi, xf, yf;
  132.  
  133.  
  134.     xi = p->x = Max(r1->x, r2->x);
  135.     yi = p->y = Max(r1->y, r2->y);
  136.     xf = Min(r1->x + r1->w, r2->x + r2->w) - 1;
  137.     yf = Min(r1->y + r1->h, r2->y + r2->h) - 1;
  138.  
  139.     p->w = xf - xi + 1;
  140.     p->h = yf - yi + 1;
  141.  
  142.     return (p->w > 0 && p->h > 0) ? p : 0;
  143. }
  144.  
  145. /***************************************************************
  146.  * check if r1 contains r2
  147.  **************************************************************/
  148. int
  149. cover_rect(const Rect_t *r1, const Rect_t *r2)
  150. {
  151.     return (r1->x <= r2->x && r1->y <= r2->y &&
  152.         (r1->x + r1->w - 1) >= (r2->x + r2->w - 1) &&
  153.         (r1->y + r1->h - 1) >= (r2->y + r2->h - 1));
  154. }
  155.  
  156. const Rect_t *
  157. sum_rect(const Rect_t *r1, const Rect_t *r2)
  158. {
  159.     static Rect_t sr[MAX_RECT_BUF];
  160.     static int nb;
  161.     register Rect_t *p = sr + (nb++ % MAX_RECT_BUF);
  162.     register int xf, yf;
  163.  
  164.     p->x = Min(r1->x, r2->x);
  165.     p->y = Min(r1->y, r2->y);
  166.     xf = Max(r1->x + r1->w - 1, r2->x + r2->w - 1);
  167.     yf = Max(r1->y + r1->h - 1, r2->y + r2->h - 1);
  168.     p->w = xf - p->x + 1;
  169.     p->h = yf - p->y + 1;
  170.  
  171.     return p;
  172. }
  173.  
  174. void
  175. print_rect(const char *n, const Rect_t *r)
  176. {
  177.     fprintf(stderr, "%s: X=%d Y=%d W=%d H=%d\n",
  178.         n, r->x, r->y, r->w, r->h);
  179. }
  180.  
  181. #if 0
  182. /****************************************************************
  183.  * Find all regions that does not overlap with r1
  184.  * (r2 U r1) - r1
  185.  ***************************************************************/
  186.  /**** TO BE WRITTEN ****/
  187. Rect_t *
  188. rect_exclude(Rect_t *r1, Rect_t *r2, int *n)
  189. {
  190.     static Rect_t reg[4];
  191.     int x1f, x2f, y1f, y2f;
  192.     register Rect_t *p = reg;
  193.  
  194.     *n = 0;
  195.  
  196.     if (!rect_overlap(r1, r2))
  197.       {
  198.       *n = 1;
  199.       return r2;
  200.       }
  201.  
  202.     /* if r1 completely covers r2 */
  203.     if (r1->x <= r2->x && r1->y <= r2->y &&
  204.     (r1->x + r1->w) >= (r2->x + r2->w) &&
  205.     (r1->y + r1->h) >= (r2->y + r2->h))
  206.       {
  207.       *n = 0;
  208.       return 0;
  209.       }
  210.  
  211.     /* r2 completely covers r1 */
  212.  
  213.     x1f = r1->x + r1->w - 1;
  214.     x2f = r2->x + r2->w - 1;
  215.     y1f = r1->y + r1->h - 1;
  216.     y2f = r2->y + r2->h - 1;
  217.  
  218.     /* partial overlap. Several cases */
  219.  
  220.     /* horizontal bound */
  221.     if (r2->x >= r1->x && x2f <= x1f)
  222.       {
  223.       if (r2->y >= r1->y)
  224.         {            /* upper vertical */
  225.         p->x = r2->x;
  226.         p->y = y1f + 1;
  227.         p->w = r2->w;
  228.         p->h = y2f - reg[*n].y;
  229.         ++p;
  230.         ++(*n);
  231.         }
  232.       else if (y2f < y1f)
  233.         {            /* lower vertical */
  234.         p->x = r2->x;
  235.         p->y = r2->y;
  236.         p->w = r2->w;
  237.         p->h = r1->y - reg[*n].y;
  238.         ++p;
  239.         ++(*n);
  240.         }
  241.       else
  242.         {            /* both upper and lower */
  243.         p->x = r2->x;
  244.         p->y = y1f + 1;
  245.         p->w = r2->w;
  246.         p->h = y2f - reg[*n].y;
  247.         ++(*n);
  248.         ++p;
  249.  
  250.         p->x = r2->x;
  251.         p->y = r2->y;
  252.         p->w = r2->w;
  253.         p->h = r1->y - reg[*n].y;
  254.         ++(*n);
  255.         ++p;
  256.         }
  257.       }
  258.     else if (r2->x > r1->x)
  259.       {                /* left */
  260.       }
  261.     else if (r2->x < r1->x)
  262.       {                /* right */
  263.       }
  264.     else
  265.       {                /* mixed */
  266.       }
  267.     return reg;
  268. }
  269. #endif
  270.